package com.loe.ui.view

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import androidx.annotation.Keep
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.chad.library.adapter.base.BaseViewHolder
import com.loe.json_ext.*
import com.loe.mvp.ext_java.safe
import com.loe.mvp.list.CustomLoadMoreView
import com.loe.mvp.list.QuickAdapter
import com.loe.ui.*
import com.loe.ui.R
import com.loe.ui.api.IUiView
import com.loe.ui.api.ListViewApi
import com.loe.ui.page.UiPage
import com.loe.ui.quickjs.jsColor
import com.quickjs.JSArray
import com.quickjs.JSObject

@Keep
open class UiListView : RecyclerView, IUiView
{
    constructor(context: Context) : super(context)
    {
        init(context)
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    {
        init(context)
    }

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    {
        init(context)
    }

    private fun init(context: Context)
    {
    }

    override val jsObject by lazy { ListViewApi(this).jsObject }

    private var isScroll = true

    var headerView: View? = null
        private set

    var footerView: View? = null
        private set

    var emptyView: View? = null
        private set

    private var decoration: ItemDecoration? = null

    private var itemConvert: (UiPage.(holder: BaseViewHolder, data: JSObject) -> Unit)? = null

    /** 设置自定义Item处理 */
    fun setItemConvert(itemConvert: UiPage.(holder: BaseViewHolder, data: JSObject) -> Unit)
    {
        this.itemConvert = itemConvert
    }

    fun setData(array: JSArray)
    {
        uiAdapter?.setNewData(array.toList())
    }

    override fun setUI(ui: JSObject, uiPage: UiPage?): View
    {
        val type = ui.gotString("type")
        var spanCount = 1
        val orientation = if (ui.gotString("orientation") == "h") HORIZONTAL else VERTICAL
        val reverse = ui.gotBoolean("reverse")

        layoutManager = when (type)
        {
            "GridUI" ->
            {
                spanCount = ui.gotInt("spanCount")
                if (spanCount < 2) spanCount = 2
                GridLayoutManager(context, spanCount, orientation, reverse)
            }
            "FallUI" ->
            {
                spanCount = ui.gotInt("spanCount")
                if (spanCount < 2) spanCount = 2
                StaggeredGridLayoutManager(spanCount, orientation)
            }
            else ->
            {
                LinearLayoutManager(context, orientation, reverse)
            }
        }

        // click
        if (ui.contains("isClick")) setClick(ui.gotBoolean("isClick"))

        // item
        val itemUI = ui.gotObject("item")

        uiAdapter = object : QuickAdapter<JSObject>(if (orientation == VERTICAL) R.layout.item_ui_v else R.layout.item_ui_h)
        {
            override fun View.convert(holder: BaseViewHolder, data: JSObject)
            {
                val page = holder.itemView as UiPage
                safe()
                {
                    if (!page.hasUI) page.setUI(itemUI)
                    itemConvert?.let { page.it(holder, data) }
                }
            }
        }
        adapter = uiAdapter

        uiAdapter?.setHeaderFooterEmpty(true, true)
        uiAdapter?.setLoadMoreView(CustomLoadMoreView())

        // itemConvert
        ui.gotHasFunction("itemConvert")
        { callback ->
            setItemConvert()
            { holder, data ->
                val i = holder.adapterPosition - (if (headerView != null) 1 else 0)
                callback.call(this@UiListView.jsObject, JSArray(jsContext).push(jsObject).push(data).push(i))
            }
        }

        // onLoadData
        ui.gotHasFunction("onLoadData")
        { callback ->
            setOnLoadData()
            { isRefresh ->
                safe { callback.call(jsObject, JSArray(jsContext).push(isRefresh)) }
            }
        }

        // header
        ui.gotHasObject("header")
        {
            headerView = uiPage?.createUI(it)
            uiAdapter?.addHeaderView(headerView)
        }

        // footer
        ui.gotHasObject("footer")
        {
            footerView = uiPage?.createUI(it)
            uiAdapter?.addFooterView(footerView)
        }

        // empty
        ui.gotHas("empty")
        {
            emptyView = if (it is JSObject)
            {
                uiPage?.createUI(it)
            } else
            {
                inflate(context, R.layout.layout_list_empty, null)
            }
            uiAdapter?.emptyView = emptyView
        }

        // listPadding
        if (decoration != null) removeItemDecoration(decoration!!)
        decoration = ui.getListPadding(spanCount, orientation, headerView != null)
        addItemDecoration(decoration!!)

        // isRefresh
        ui.gotHasBoolean("isRefresh")
        {
            isEnableRefresh = it
            if (!isEnableRefresh)
            {
                refreshLayout?.setOnClickListener(null)
                refreshLayout = null
            }
        }

        // loadMore
        ui.gotHasBoolean("isLoadMore")
        {
            isEnableLoadMore = ui.gotBoolean("isLoadMore")
            uiAdapter?.setEnableLoadMore(isEnableLoadMore)
            if (isEnableLoadMore)
            {
                // 加载更多监听
                uiAdapter?.setOnLoadMoreListener({
                    refreshLayout?.isEnabled = false

                    postDelayed({
                        onLoadData?.invoke(false)
                    }, 400)
                }, this)
            } else
            {
                uiAdapter?.setOnLoadMoreListener(null, this)
            }
        }

        // isScroll
        ui.gotHasBoolean("isScroll")
        {
            isScroll = it
            isNestedScrollingEnabled = isScroll
        }
        // maxHeight
        ui.gotHasString("maxHeight") { maxHeight = it.px }
        // maxWidth
        ui.gotHasString("maxWidth") { maxWidth = it.px }
        // scrollSize
        ui.gotHasString("scrollSize") { scrollBarSize = it.px }
        // refreshColor
        ui.gotHasString("refreshColor")
        {
            refreshColor = it.color
            refreshLayout?.setColorSchemeColors(refreshColor!!)
        }

        // onListScroll
        ui.gotHasFunction("onListScroll")
        { callback ->
            onListScroll = { position, top -> safe { callback.call(jsObject, JSArray(jsContext).push(position).push(top)) } }
        }

        // datas
        ui.gotHasArray("datas")
        {
            if (it.length() > 0)
            {
                val o = it.get(0)
                if (o is JSObject)
                {
                    uiAdapter?.setNewData(it.toList())
                } else
                {
                    val list = it.toList<String>().map { value -> JSObject(jsContext).set("value", value) }
                    uiAdapter?.setNewData(list)
                }
            } else
            {
                uiAdapter?.setNewData(it.toList())
            }
        }

        return if (ui.gotBoolean("isRefresh"))
        {
            // 塞入refresh
            refreshLayout = SwipeRefreshLayout(context)
            refreshLayout?.isEnabled = true
            val listParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
            refreshLayout?.addView(this, listParams)
            refreshLayout!!
        } else
        {
            this
        }
    }

    override var onSelect: (() -> Unit)? = null

    /********************************************** 点击 ****************************************/

    fun setClick(isClick: Boolean)
    {
        isAlpha = isClick
        isClickable = isClick
    }

    private var isAlpha = false

    override fun dispatchSetPressed(pressed: Boolean)
    {
        if (isAlpha) alpha = if (pressed || !isEnabled) 0.75f else 1f
        super.dispatchSetPressed(pressed)
    }

    override fun setEnabled(enabled: Boolean)
    {
        if (isAlpha) alpha = if (enabled) 1f else 0.75f
        super.setEnabled(enabled)
    }

    /*****************************************   滚动   ****************************************/

    var onListScroll: ((position: Int, top: Int) -> Unit)? = null

    override fun onScrolled(dx: Int, dy: Int)
    {
        if (onListScroll != null)
        {
            val topView = getChildAt(0)
            val position = (topView.layoutParams as LayoutParams).viewAdapterPosition
            val top = topView.top
            onListScroll!!(position, top)
        }
    }

    /***************************************** 加载刷新 ****************************************/

    private var refreshColor: Int? = null

    /** 刷新View */
    var refreshLayout: SwipeRefreshLayout? = null
        set(value)
        {
            if (isEnableRefresh)
            {
                field = value
                value?.isEnabled = true
                if (refreshColor != null)
                {
                    value?.setColorSchemeColors(refreshColor!!)
                } else
                {
                    value?.setColorSchemeColors(jsColor.main.color)
                }
                // 刷新监听
                value?.setOnRefreshListener()
                {
                    if (isEnableLoadMore) uiAdapter?.setEnableLoadMore(false)

                    postDelayed({
                        page == 1
                        onLoadData?.invoke(true)
                    }, 400)
                }
            } else
            {
                field = null
            }
        }

    fun refresh()
    {
        refreshLayout?.measure(0, 0)
        refreshLayout?.isRefreshing = true
    }

    fun refreshAuto()
    {
        if (uiAdapter?.data?.isEmpty() == true)
        {
            refresh()
        }
    }

    fun setRefreshing(refreshing: Boolean)
    {
        refreshLayout?.isRefreshing = refreshing
    }

    var size: Int = 10

    private var isEnableLoadMore = false

    private var isEnableRefresh = false

    var uiAdapter: QuickAdapter<JSObject>? = null
        private set

    var page = 1
        private set

    /** 加载监听 */
    private var onLoadData: ((isRefresh: Boolean) -> Unit)? = null

    /** 设置加载监听 */
    fun setOnLoadData(onLoadData: (isRefresh: Boolean) -> Unit)
    {
        this.onLoadData = onLoadData
    }

    fun loadData(isRefresh: Boolean = true)
    {
        if (isRefresh) page = 1
        onLoadData?.invoke(isRefresh)
    }

    /**
     * 加载完成调用
     */
    fun loadOk(aList: List<JSObject>, isRefresh: Boolean)
    {
        if (isEnableLoadMore)
        {
            refreshLayout?.isRefreshing = false
            if (isRefresh)
            {
//                size = 10
                uiAdapter?.data?.clear()
            }
            uiAdapter?.addData(aList)
            if (isRefresh)
            {
                refreshLayout?.isRefreshing = false
                uiAdapter?.setEnableLoadMore(true)
            } else
            {
                uiAdapter?.loadMoreComplete()
                refreshLayout?.isEnabled = true
            }
//            if (aList.size < size)
//            {
////                adapter.setEnableLoadMore(false)
//                adapter.loadMoreEnd(false)
//            } else
//            {
//                size = aList.size
//            }
            if (aList.isEmpty() || aList.size < size)
            {
                uiAdapter?.loadMoreEnd(false)
            }
            page++
        } else
        {
            refreshLayout?.isRefreshing = false
            uiAdapter?.data?.clear()
            uiAdapter?.addData(aList)
        }
    }

    fun loadOk(aArray: JSArray, isRefresh: Boolean)
    {
        loadOk(aArray.toList(), isRefresh)
    }

    /**
     * 加载失败调用
     */
    fun loadError(isRefresh: Boolean)
    {
        if (isEnableLoadMore)
        {
            if (isRefresh)
            {
                refreshLayout?.isRefreshing = false
            } else
            {
                uiAdapter?.loadMoreFail()
                refreshLayout?.isEnabled = true
            }
        } else
        {
            refreshLayout?.isRefreshing = false
        }
    }

    operator fun get(i: Int): JSObject = uiAdapter?.getItem(i) ?: JSObject(jsContext)

    operator fun set(i: Int, data: JSObject) = uiAdapter?.setData(i, data)

    private var maxHeight = 0
    private var maxWidth = 0

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)
    {
        if (!isScroll)
        {
            // ListView适应ScrollView的效果
            val heightSpec = MeasureSpec.makeMeasureSpec(Int.MAX_VALUE shr 2, MeasureSpec.AT_MOST)
            super.onMeasure(widthMeasureSpec, heightSpec)
        } else
        {
            var widthSpec = widthMeasureSpec
            var heightSpec = heightMeasureSpec
            if (maxHeight > 0)
            {
                heightSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST)
            }
            if (maxWidth > 0)
            {
                widthSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST)
            }

            super.onMeasure(widthSpec, heightSpec)
        }
    }
}